package com.cskaoyan.search.service.impl;

import com.cskaoyan.mall.dto.ProductDto;
import com.cskaoyan.search.converter.ProductConverter;
import com.cskaoyan.search.dto.SearchResponse;
import com.cskaoyan.search.entity.ItemDocument;
import com.cskaoyan.search.form.SearchRequest;
import com.cskaoyan.search.repository.ProductRepository;
import com.cskaoyan.search.service.ProductSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: 杨庆
 * @since: 2022.9.27 19:45
 * @description:
 */

@Service
@Slf4j
public class ProductSearchServiceImpl implements ProductSearchService {

    @Autowired
    ProductRepository productRepository;
    @Autowired
    ProductConverter productConverter;

    @Autowired
    ElasticsearchRestTemplate restTemplate;

    /**
    * @description: 返回查询的结果
    [request]
    * @return: com.cskaoyan.search.dto.SearchResponse
    * @author: 杨庆
    * @time: 2022.9.27 20:25
     */
    @Override
    public SearchResponse search(SearchRequest request) {
        //TODO 根据搜索的关键自返回信息
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", request.getKey());
        boolQueryBuilder.must(matchQueryBuilder);
        //TODO 根据价格查询
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
        if (request.getPriceGt() != null) {
            rangeQueryBuilder.gt(request.getPriceGt());
        }
        if (request.getPriceLte() != null) {
            rangeQueryBuilder.lte(request.getPriceLte());
        }
        boolQueryBuilder.filter(rangeQueryBuilder);
        queryBuilder.withQuery(boolQueryBuilder);
        //TODO 构造分页
        String sortId = request.getSort();
        Sort orders =null;
        if (!StringUtils.isEmpty(sortId)) {
            int sortIds = Integer.parseInt(sortId);
            if (sortIds == 1) {
                 orders = Sort.by(Sort.Direction.ASC,"price");
            }
            if (sortIds == -1) {
                orders = Sort.by(Sort.Direction.DESC,"price");

            }
        }
        PageRequest pageInfo=null;
        if (orders != null) {
             pageInfo = PageRequest.of(request.getPage() - 1, request.getSize(), orders);
        } else {
             pageInfo = PageRequest.of(request.getPage()-1, request.getSize());
        }
        queryBuilder.withPageable(pageInfo);
        //TODO 添加高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title").preTags("<font color='red'>").postTags("</font>");
        queryBuilder.withHighlightBuilder(highlightBuilder);
        //TODO 发起请求
        NativeSearchQuery build = queryBuilder.build();
        SearchHits<ItemDocument> search = restTemplate.search(build, ItemDocument.class);
        long totalHits = search.getTotalHits();


        List<SearchHit<ItemDocument>> searchHits = search.getSearchHits();

        ArrayList<ItemDocument> itemDocuments = new ArrayList<>();
        searchHits.forEach(itemDocumentSearchHit -> {
            ItemDocument content = itemDocumentSearchHit.getContent();
            List<String> title = itemDocumentSearchHit.getHighlightField("title");
            content.setTitle(title.get(0));
            itemDocuments.add(content);
        });

        List<ProductDto> list = productConverter.items2Dto(itemDocuments);


        SearchResponse<ProductDto> searchResponse = new SearchResponse<>();
        searchResponse.setData(list);
        searchResponse.setTotal(totalHits);

        return searchResponse;
    }

    /**
    * @description: 返回搜索的
    [request]
    * @return: com.cskaoyan.search.dto.SearchResponse
    * @author: 杨庆
    * @time: 2022.9.27 19:45
     */
    @Override
    public SearchResponse fuzzySearch(SearchRequest request) {
        SearchResponse<ProductDto> objectSearchResponse = new SearchResponse<>();
        // Sort sort = Sort.by(Sort.Direction.DESC, "price");
        // PageRequest pageInfo = PageRequest.of(request.getPage(), request.getSize(), sort);
        PageRequest pageInfo = PageRequest.of(request.getPage(), request.getSize());
        Page<ItemDocument> itemDocuments = productRepository.testSearchPage(request.getKey(), pageInfo);
        List<ProductDto> list = new ArrayList<>();
        itemDocuments.forEach(itemDocument -> {
            ItemDocument item  =itemDocument;
            ProductDto productDto = productConverter.item2Dto(item);
            list.add(productDto);
        });
        objectSearchResponse.setData(list);
        objectSearchResponse.setTotal(itemDocuments.getTotalElements());
        return objectSearchResponse;
    }
}
